package py.edu.ucsa.sisale.access.dao;

import java.util.Collection;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import py.edu.ucsa.sisale.access.domain.User;

@Repository
public class UserRepositoryImpl implements UserRepository {

	@PersistenceContext
	private EntityManager em;

	@Transactional
	public Collection<User> loadUsers() {
		Query query = em.createQuery("from User");
		return query.getResultList();
	}

	@Transactional
	public void saveUser(User user) {
		// em.createNativeQuery("insert into user (username, accountExpired, accountLocked, enabled) values (:a, :b, :c, :d)")
		// .setParameter("a", user.getUsername()).setParameter("b", new
		// Date()).setParameter("c", false).setParameter("d",
		// false).executeUpdate();
		em.persist(user);

	}

	@Transactional(readOnly = true)
	public String findPasswordByUsername(String username) {
		return (String) em
				.createQuery(
						"select u.username from User u where u.username = :username")
				.setParameter("username", username).getSingleResult();
	}

	@Transactional(readOnly = true)
	public boolean isEmailAlreadyExists(String email) {
		Long count = (Long) em
				.createQuery(
						"select count(u.username) from User u where u.username= :email")
				.setParameter("email", email).getSingleResult();
		if (count.compareTo(0l) > 0) {
			return true;
		}
		return false;

	}

	@Transactional(readOnly = true)
	public User findUserByUsername(String username) {
		Query query = em
				.createQuery("select u from User u where u.username = :username and u.enabled = :enabled");
		query.setParameter("username", username);
		query.setParameter("enabled", true); // traemos solo el usuario
												// habilitado
		List<User> userlList = query.getResultList();
		return (User) userlList.get(0);
	}

	@Transactional(readOnly = true)
	public User findUserByEmail(String email) {
		return (User) em.createQuery("select u from User u where u.username = :email").setParameter("email", email).getSingleResult();
	}

	@Transactional
	public void update(User user) {
		em.merge(user);
	}

	@Transactional(readOnly = false)
	public List<String> findUsername(String username) {
		Query query = em
				.createQuery(
						"select u.username from User u where u.username like :username")
				.setParameter("username", username + "%").setMaxResults(5);
		return query.getResultList();
	}

	@Transactional(readOnly = true)
	public boolean isSecurityCodeValid(String email, String securityCode) {
		Query query = em
				.createQuery(
						"select count(u) from User u join u.securityCode as sec where u.username = :email"
								+ " and sec.code = :code")
				.setParameter("email", email)
				.setParameter("code", securityCode);
		Long count = (Long) query.getSingleResult();
		return count == 1;
	}

}
